package com.flute.icrawler.app.task;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flute.icrawler.app.task.entity.CrawlTask;

public class CrawlTaskManager extends Thread {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(CrawlTaskManager.class);

	private CrawlTaskPool crawlTaskPool = new CrawlTaskPool();

	// 对任务池的轮询时间
	private long WAITTIME = 20000;

	public CrawlTaskManager() {
		// 向系统注册Hook，系统关闭时将所有任务设置成不在池中
		Runtime.getRuntime().addShutdownHook(
				new CrawlTaskEndHook(crawlTaskPool));

	}

	public void beforeShutdown() {

		for (int i = 0; i < crawlTaskPool.size(); i++) {

			CrawlTask crawlTask = crawlTaskPool.get(i);
			if (crawlTask.isFinished()) {
				crawlTask.setFinished();
			}

		}

	}

	@Override
	public void run() {

		// 启动时先等待30秒
		try {
			sleep(30000);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}

		while (true) {

			checkTaskState();
			innerStart();

			try {
				LOGGER.info("Check task pool after " + WAITTIME / 1000 + " s");
				sleep(WAITTIME);
			} catch (InterruptedException e) {
				LOGGER.info(e.getLocalizedMessage());
			}

		}

	}

	/**
	 * 循环监控当前的任务池
	 */
	private void innerStart() {
		for (int i = 0; i < crawlTaskPool.size(); i++) {
			CrawlTask crawlTask = crawlTaskPool.get(i);

			ITaskState state = crawlTask.getTaskState().handle(
					crawlTaskPool.get(i));

			crawlTask.setTaskState(state);

		}
	}

	/**
	 * 监控JSP页面创建的任务目录 获取任务列表 发现任务配置文件名字为则加入的任务池中
	 */
	private void checkTaskState() {

		// 任务列表目录
		// -------------------任务名称
		// --------------------------任务配置文件 目前只有一个该文件
		// --------------------------任务描述文件 目前只有一个该文件
		File file = new File(CrawlTask.TASK_LIST);

		// 下级目录名为任务名称
		File[] files = file.listFiles();

		if (null == files) {
			return;
		}

		// 循环一次处理一个任务
		for (int i = 0; i < files.length; i++) {

			// 任务名称
			String taskName = files[i].getName();

			// 如果池中包含了该任务 则不处理
			if (crawlTaskPool.contain(taskName)) {
				LOGGER.debug("Echo crawlTask name=" + taskName);
				continue;
			}

			// 没有包含该任务则新生成一个任务对象
			CrawlTask crawlTask = new CrawlTask(taskName);
			long currentTime = System.currentTimeMillis();
			long finishTime = crawlTask.getFinishTime();

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
					"yyyy-MM-dd'T'HH:mm:ss");
			LOGGER.info("Create new crawlTask " + ";currentTime="
					+ simpleDateFormat.format(new Date(currentTime))
					+ ";finishTime="
					+ simpleDateFormat.format(new Date(finishTime))
					+ ";interval=" + crawlTask.getIntervalDay() + " Name="
					+ taskName + "finishTime_long = " + finishTime);

			try {
				crawlTask.checkState();
			} catch (Exception e) {
				e.printStackTrace();
			}
			// 将所有发现的任务加入队列
			crawlTaskPool.addCrawlTask(crawlTask);
			LOGGER.info("Add 1 crawlTask to pool Name=" + taskName);

		}
	}
}

class CrawlTaskEndHook extends Thread {

	private CrawlTaskPool crawlTaskPool = null;

	public CrawlTaskEndHook(CrawlTaskPool crawlTaskPool) {
		this.crawlTaskPool = crawlTaskPool;
	}

	@Override
	public void run() {

		for (int i = 0; i < crawlTaskPool.size(); i++) {

			CrawlTask crawlTask = crawlTaskPool.get(i);
			if (crawlTask.isFinished()) {
				crawlTask.setFinished();
			}

		}
	}
}
